package com.ls.herostory.rank;

import com.ls.herostory.mq.AttkMsg;
import com.ls.herostory.msg.GameMsgProtocol;
import com.ls.herostory.thread.AsyncOperation;
import com.ls.herostory.thread.AsyncOperationProcessor;
import com.ls.herostory.util.RedisUtil;
import org.redisson.api.RMap;
import org.redisson.api.RScoredSortedSet;
import org.redisson.api.RedissonClient;
import org.redisson.client.protocol.ScoredEntry;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.function.Consumer;

/**
 * @author liangsu
 * @version v1.0
 * @Description
 * @Date 2020/10/14 17:25
 * @since
 */
public class RankRedisManager {
    private static RankRedisManager instance = new RankRedisManager();
    private RankRedisManager(){}
    public static RankRedisManager getIntance(){
        return instance;
    }

    private RedissonClient redisson = RedisUtil.getRedisson();

    public void updateScore(AttkMsg msg){
        // 设置用户信息
        String userKey = "rank_user";
        RMap<Object, Object> map = redisson.getMap(userKey);
        if(!map.containsKey(msg.getUserId())){
            map.put(msg.getUserId(), msg);
        }
        Integer score = (Integer) map.get("socre_" + msg.getUserId());
        score = score == null ? 0 : score;
        score++;
        map.put("socre_" + msg.getUserId(), score);

        // 设置分值
        RScoredSortedSet<Object> rankSet = redisson.getScoredSortedSet("rank_set");
        rankSet.add(score, msg.getUserId());
    }

    public void asyncGetRanks(Consumer<List<GameMsgProtocol.GetRankResult.RankItem>> consumer){
        AsyncOperation asyncOperation = new AsyncOperation() {

            List<GameMsgProtocol.GetRankResult.RankItem> rankItems = new ArrayList<>();

            @Override
            public void doAsync() {
                RScoredSortedSet<Integer> rankSet = redisson.getScoredSortedSet("rank_set");
                Collection<ScoredEntry<Integer>> scoredEntries = rankSet.entryRangeReversed(0, 9);

                int rankId = 1; // 排名
                for (ScoredEntry<Integer> entry : scoredEntries) {
                    System.out.println(entry.getValue() + ": " + entry.getScore());
                    GameMsgProtocol.GetRankResult.RankItem.Builder builder = GameMsgProtocol.GetRankResult.RankItem.newBuilder();

                    RMap<Object, Object> userMap = redisson.getMap("rank_user"); // 获取用户
                    AttkMsg user = (AttkMsg) userMap.get(entry.getValue());
                    if(user != null){
                        builder.setUserId(user.getUserId())
                                .setUserName(user.getUserName())
                                .setHeroAvatar(user.getHeroAvatar());
                    }
                    builder.setRankId(rankId);
                    builder.setWin(entry.getScore().intValue());
                    rankItems.add(builder.build());
                    rankId++;
                }
            }

            @Override
            public void doFinish() {
                consumer.accept(rankItems);
            }
        };

        AsyncOperationProcessor.getIntance().process(asyncOperation);
    }

}
